46_SPI Progress

Today I worked more on trying to get a SPI (Serial Peripheral Interface) set up between out MCU and external ADC.  Previously, the dsPIC30 was being used to try to communicate with the ADC.  Now we can use the dsPIC33.

It turns out that the data sheet for the dsPIC33 happened to be more detailed than the one for the dsPIC30, so setting up a SPI interface was more straightforward.  Following general SPI setup example in one of the dsPIC33E family datasheets, a SPI initialization function was created (Figure 1).  After calling this function, any data written to the SPI1BUF register can be observed on an oscilloscope being output one bit at a time on the SPI1 module’s output pin, SDO1.  Figure 2 shows the hexadecimal number 0x0008 being sent out from the SPI module by writing a 0x0008 to the SPI1BUF register.
Figure 1: SPI Initialization Function


Figure 2:  SPI1 Module Outputting a START/SYNC Command (0x0008)

According to the ADC’s data sheet (ADS1120), sending a 0x08 command to the module will tell it to begin converting (START/SYNC).  It is in “single-shot” mode by default, meaning that this command must be sent for each analog value converted.  Later, the ADC will probably be set to “continuous mode” where conversions are continuous after the “begin” command.  The SPI module was set up with 16-bit communication form, but later I’ll try to modify the mode to 8-bit form when commands are being sent since the ADC accepts commands in 8-bit form.  Although a 16-bit command can be sent, the ADC will read the 2 bytes in the 16-bit word sequentially, meaning that sending a 0x0008 will first be read as a 0x08 (START/SYNC) then a 0x00 (nothing).
So after sending a 0x0008, the ADC was observed outputting a binary signal as in Figure 3.  I had AIN0 plugged into +3.3V.  By default, the ADC uses its internal 2.048V reference, so it should read the 3.3V as the max value it can convert.  As shown in the image, the binary value sent was 0111 1111 1111 1111 (0x7FFF).  Because it’s signed binary, this value converts to a decimal value of +32767.  Scaling this value against the 2.048V reference (32767 * (2.048V/32767)) gives 2.048V.

Figure 3: ADC Converting 3.3V to Binary Signal

Next I plugged the AIN0 pin into Ground.  It sent back the signal in Figure 4, 0x0000 which scaled to 0.0V.

Figure 4:  ADC Converting 0.0V to Binary Signal

Then, I plugged AIN0 into 0.1V and it sent the signal in Figure 5, 0x0767 which equals 1895 in decimal and scales to (1895 * (2.048V/32767)) = .118V.  I measured the actual voltage of the “0.1V signal” as .096V, so the ADC was off by about 22mV which will be a problem if it’s receiving un-amplified signals from the EMG system.  The ADC has an internal amplifier though, which will probably be used to hopefully reduce the effect of reading errors like this.

Figure 5:  ADC Converting 0.1V to Binary Signal

I tried plugging AIN0 into a negative voltage, and although it did convert the value properly, it began overheating.  It’s probably because I was only giving it an analog power range from 0 to 3.3V.